package com.ml4ai.backend.security;

import com.ml4ai.backend.domain.Authority;
import com.ml4ai.backend.domain.Resource;
import com.ml4ai.backend.repository.AuthorityRepo;
import com.ml4ai.backend.repository.ResourceRepo;
import com.ml4ai.backend.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by uesr on 2018/9/9.
 */
@Component
@Slf4j
public class SecurityAuthMetadataSourceImpl implements SecurityAuthMetadataSource {

    @Autowired
    private AuthorityRepo authorityRepo;

    @Autowired
    private ResourceRepo resourceRepo;

    @Value("${debug}")
    private Boolean debug;

    private Map<String, Collection<ConfigAttribute>> resourceMap = null;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    // 在Web服务器启动时，提取系统中的所有权限
    public void loadResource() {
        Iterator<Resource> resources = resourceRepo.findAvilable().iterator();
        this.resourceMap = new HashMap<>();
        while (resources.hasNext()) {
            Resource resource = resources.next();
            List<ConfigAttribute> list = resource.getAuthorities().stream().filter(a -> a.getStatus().equals("1")).map(Authority::getAuthority).map(SecurityConfig::new).collect(Collectors.toList());
            this.resourceMap.put(resource.getResource(), list);
        }
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        List<Authority> authorities = authorityRepo.findAvilable();
        return authorities.stream().map(Authority::getAuthority).map(SecurityConfig::new).collect(Collectors.toList());
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        if (resourceMap == null) {
            loadResource();
        }
        List<ConfigAttribute> list = new ArrayList<>();
        String url = ((FilterInvocation) object).getRequestUrl();
        Set<String> urlPatterns = resourceMap.keySet();
        for (String urlPattern : urlPatterns) {
            if (antPathMatcher.match(urlPattern, url)) {
                list.addAll(resourceMap.get(urlPattern));
            }
        }
        return list;
    }

    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }
}
